package com.zelin.java.test1;


/**
 * 实现一个简单的死锁
 * 
 * 创建A，B两个对象
 * 
 * A抢占A的锁
 * B抢占B的锁
 * 
 * A去抢占B的锁，发现B的锁已经被抢占，A等待B的锁释放，这个时候，只要B线程运行结束，就会释放B的锁
 * B去抢占A的锁，发现A的锁也被抢占，B等待A的锁释放
 * 
 * 这时就产生了一个死循环，AB的锁永远都释放不了，产生死锁
 */
public class Test1 {
	
	public static void main(String[] args) {
		AThread aThread = new AThread();
		BThread bThread = new BThread();
		aThread.setbThread(bThread);
		bThread.setaThread(aThread);
		
		new Thread(aThread).start();
		new Thread(bThread).start();
	}

}

class AThread implements Runnable {
	
	private BThread bThread;
	
	public void setbThread(BThread bThread) {
		this.bThread = bThread;
	}

	@Override
	public void run() {
		lockA();
	}
	
	// 锁定A对象
	public synchronized void lockA() {
		System.out.println("Lock AThread...");
		// 锁定B对象，发现B对象已经被锁定，等待B对象释放锁
		bThread.lockBForA();
	}
	
	public synchronized void lockAForB() {
		System.out.println("Lock AThread Success...");
	}
	
}

class BThread implements Runnable {

	private AThread aThread;
	
	public void setaThread(AThread aThread) {
		this.aThread = aThread;
	}
	
	@Override
	public void run() {
		lockB();
	}
	
	// 锁定B对象
	public synchronized void lockB() {
		System.out.println("Lock AThread...");
		// 锁定A对象，发现A对象已经被锁定，等待A对象释放锁
		aThread.lockAForB();
	}
	
	public synchronized void lockBForA() {
		System.out.println("Lock BThread Success...");
	}
	
}
